/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controllers;

import Controllers.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entities.Pet;
import java.util.ArrayList;
import java.util.List;
import Entities.Appointment;
import Entities.Person;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author Heinz Hernandez
 */
public class PersonJpaController implements Serializable {

    public PersonJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Person person) {
        if (person.getPetList() == null) {
            person.setPetList(new ArrayList<Pet>());
        }
        if (person.getPetList1() == null) {
            person.setPetList1(new ArrayList<Pet>());
        }
        if (person.getAppointmentList() == null) {
            person.setAppointmentList(new ArrayList<Appointment>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Pet> attachedPetList = new ArrayList<Pet>();
            for (Pet petListPetToAttach : person.getPetList()) {
                petListPetToAttach = em.getReference(petListPetToAttach.getClass(), petListPetToAttach.getPetId());
                attachedPetList.add(petListPetToAttach);
            }
            person.setPetList(attachedPetList);
            List<Pet> attachedPetList1 = new ArrayList<Pet>();
            for (Pet petList1PetToAttach : person.getPetList1()) {
                petList1PetToAttach = em.getReference(petList1PetToAttach.getClass(), petList1PetToAttach.getPetId());
                attachedPetList1.add(petList1PetToAttach);
            }
            person.setPetList1(attachedPetList1);
            List<Appointment> attachedAppointmentList = new ArrayList<Appointment>();
            for (Appointment appointmentListAppointmentToAttach : person.getAppointmentList()) {
                appointmentListAppointmentToAttach = em.getReference(appointmentListAppointmentToAttach.getClass(), appointmentListAppointmentToAttach.getAppoId());
                attachedAppointmentList.add(appointmentListAppointmentToAttach);
            }
            person.setAppointmentList(attachedAppointmentList);
            em.persist(person);
            for (Pet petListPet : person.getPetList()) {
                Person oldPerIdownOfPetListPet = petListPet.getPerIdown();
                petListPet.setPerIdown(person);
                petListPet = em.merge(petListPet);
                if (oldPerIdownOfPetListPet != null) {
                    oldPerIdownOfPetListPet.getPetList().remove(petListPet);
                    oldPerIdownOfPetListPet = em.merge(oldPerIdownOfPetListPet);
                }
            }
            for (Pet petList1Pet : person.getPetList1()) {
                Person oldPerIdOfPetList1Pet = petList1Pet.getPerId();
                petList1Pet.setPerId(person);
                petList1Pet = em.merge(petList1Pet);
                if (oldPerIdOfPetList1Pet != null) {
                    oldPerIdOfPetList1Pet.getPetList1().remove(petList1Pet);
                    oldPerIdOfPetList1Pet = em.merge(oldPerIdOfPetList1Pet);
                }
            }
            for (Appointment appointmentListAppointment : person.getAppointmentList()) {
                Person oldPerIdOfAppointmentListAppointment = appointmentListAppointment.getPerId();
                appointmentListAppointment.setPerId(person);
                appointmentListAppointment = em.merge(appointmentListAppointment);
                if (oldPerIdOfAppointmentListAppointment != null) {
                    oldPerIdOfAppointmentListAppointment.getAppointmentList().remove(appointmentListAppointment);
                    oldPerIdOfAppointmentListAppointment = em.merge(oldPerIdOfAppointmentListAppointment);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Person person) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Person persistentPerson = em.find(Person.class, person.getPerId());
//            List<Pet> petListOld = persistentPerson.getPetList();
//            List<Pet> petListNew = person.getPetList();
//            List<Pet> petList1Old = persistentPerson.getPetList1();
//            List<Pet> petList1New = person.getPetList1();
//            List<Appointment> appointmentListOld = persistentPerson.getAppointmentList();
//            List<Appointment> appointmentListNew = person.getAppointmentList();
//            List<Pet> attachedPetListNew = new ArrayList<Pet>();
//            for (Pet petListNewPetToAttach : petListNew) {
//                petListNewPetToAttach = em.getReference(petListNewPetToAttach.getClass(), petListNewPetToAttach.getPetId());
//                attachedPetListNew.add(petListNewPetToAttach);
//            }
//            petListNew = attachedPetListNew;
//            person.setPetList(petListNew);
//            List<Pet> attachedPetList1New = new ArrayList<Pet>();
//            for (Pet petList1NewPetToAttach : petList1New) {
//                petList1NewPetToAttach = em.getReference(petList1NewPetToAttach.getClass(), petList1NewPetToAttach.getPetId());
//                attachedPetList1New.add(petList1NewPetToAttach);
//            }
//            petList1New = attachedPetList1New;
//            person.setPetList1(petList1New);
//            List<Appointment> attachedAppointmentListNew = new ArrayList<Appointment>();
//            for (Appointment appointmentListNewAppointmentToAttach : appointmentListNew) {
//                appointmentListNewAppointmentToAttach = em.getReference(appointmentListNewAppointmentToAttach.getClass(), appointmentListNewAppointmentToAttach.getAppoId());
//                attachedAppointmentListNew.add(appointmentListNewAppointmentToAttach);
//            }
//            appointmentListNew = attachedAppointmentListNew;
//            person.setAppointmentList(appointmentListNew);
            person = em.merge(person);
//            for (Pet petListOldPet : petListOld) {
//                if (!petListNew.contains(petListOldPet)) {
//                    petListOldPet.setPerIdown(null);
//                    petListOldPet = em.merge(petListOldPet);
//                }
//            }
//            for (Pet petListNewPet : petListNew) {
//                if (!petListOld.contains(petListNewPet)) {
//                    Person oldPerIdownOfPetListNewPet = petListNewPet.getPerIdown();
//                    petListNewPet.setPerIdown(person);
//                    petListNewPet = em.merge(petListNewPet);
//                    if (oldPerIdownOfPetListNewPet != null && !oldPerIdownOfPetListNewPet.equals(person)) {
//                        oldPerIdownOfPetListNewPet.getPetList().remove(petListNewPet);
//                        oldPerIdownOfPetListNewPet = em.merge(oldPerIdownOfPetListNewPet);
//                    }
//                }
//            }
//            for (Pet petList1OldPet : petList1Old) {
//                if (!petList1New.contains(petList1OldPet)) {
//                    petList1OldPet.setPerId(null);
//                    petList1OldPet = em.merge(petList1OldPet);
//                }
//            }
//            for (Pet petList1NewPet : petList1New) {
//                if (!petList1Old.contains(petList1NewPet)) {
//                    Person oldPerIdOfPetList1NewPet = petList1NewPet.getPerId();
//                    petList1NewPet.setPerId(person);
//                    petList1NewPet = em.merge(petList1NewPet);
//                    if (oldPerIdOfPetList1NewPet != null && !oldPerIdOfPetList1NewPet.equals(person)) {
//                        oldPerIdOfPetList1NewPet.getPetList1().remove(petList1NewPet);
//                        oldPerIdOfPetList1NewPet = em.merge(oldPerIdOfPetList1NewPet);
//                    }
//                }
//            }
//            for (Appointment appointmentListOldAppointment : appointmentListOld) {
//                if (!appointmentListNew.contains(appointmentListOldAppointment)) {
//                    appointmentListOldAppointment.setPerId(null);
//                    appointmentListOldAppointment = em.merge(appointmentListOldAppointment);
//                }
//            }
//            for (Appointment appointmentListNewAppointment : appointmentListNew) {
//                if (!appointmentListOld.contains(appointmentListNewAppointment)) {
//                    Person oldPerIdOfAppointmentListNewAppointment = appointmentListNewAppointment.getPerId();
//                    appointmentListNewAppointment.setPerId(person);
//                    appointmentListNewAppointment = em.merge(appointmentListNewAppointment);
//                    if (oldPerIdOfAppointmentListNewAppointment != null && !oldPerIdOfAppointmentListNewAppointment.equals(person)) {
//                        oldPerIdOfAppointmentListNewAppointment.getAppointmentList().remove(appointmentListNewAppointment);
//                        oldPerIdOfAppointmentListNewAppointment = em.merge(oldPerIdOfAppointmentListNewAppointment);
//                    }
//                }
//            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = person.getPerId();
                if (findPerson(id) == null) {
                    throw new NonexistentEntityException("The person with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Person person;
            try {
                person = em.getReference(Person.class, id);
                person.getPerId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The person with id " + id + " no longer exists.", enfe);
            }
            List<Pet> petList = person.getPetList();
            for (Pet petListPet : petList) {
                petListPet.setPerIdown(null);
                petListPet = em.merge(petListPet);
            }
            List<Pet> petList1 = person.getPetList1();
            for (Pet petList1Pet : petList1) {
                petList1Pet.setPerId(null);
                petList1Pet = em.merge(petList1Pet);
            }
            List<Appointment> appointmentList = person.getAppointmentList();
            for (Appointment appointmentListAppointment : appointmentList) {
                appointmentListAppointment.setPerId(null);
                appointmentListAppointment = em.merge(appointmentListAppointment);
            }
            em.remove(person);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Person> findPersonEntities() {
        return findPersonEntities(true, -1, -1);
    }

    public List<Person> findPersonEntities(int maxResults, int firstResult) {
        return findPersonEntities(false, maxResults, firstResult);
    }

    private List<Person> findPersonEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Person.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Person findPerson(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Person.class, id);
        } finally {
            em.close();
        }
    }

    public int getPersonCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Person> rt = cq.from(Person.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
